﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DGZImp.MdsProject.Helper
{
    /// <summary>
    /// 一个简单的雪花ID生成器 生成int的ID 支持的并发比较低 每秒不超过256个
    /// </summary>
    public static class SimpleSnowId
    {
        private static readonly long EPOCH = 1704038400L;

        private static readonly int SEQUENCE_BITS = 8;
        private static readonly long MAX_SEQUENCE = 0xFF;

        private static long _sequence = 0L;
        private static long _lastTimestamp = -1L;

        private static object locker = new { };

        public static int GenerateId()
        {
            long timestamp = TimeGen();

            if (timestamp < _lastTimestamp)
            {
                throw new Exception("Clock moved backwards. Refusing to generate id.");
            }

            lock (locker)
            {
                if (_lastTimestamp == timestamp)
                {
                    _sequence = (_sequence + 1) & MAX_SEQUENCE;
                    if (_sequence == 0)
                    {
                        timestamp = WaitNextMillis(_lastTimestamp);
                    }
                }
                else
                {
                    _sequence = 0L;
                }
                _lastTimestamp = timestamp;
            }

            var id = ((timestamp - EPOCH) << SEQUENCE_BITS) | (_sequence & MAX_SEQUENCE);
            while (id > int.MaxValue)
            {
                id -= int.MaxValue;
            }

            return (int)id;
        }

        private static long TimeGen()
        {
            return DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        }

        private static long WaitNextMillis(long lastTimestamp)
        {
            long timestamp = TimeGen();
            while (timestamp <= lastTimestamp)
            {
                timestamp = TimeGen();
            }
            return timestamp;
        }
    }
}
